import {
  Injectable,
  ExecutionContext,
  Logger,
  UnauthorizedException,
} from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';
import { JwtService } from '@nestjs/jwt';
import { excludedRoutes } from './excluded.routes';

@Injectable()
export class JwtAuthGuard extends AuthGuard('jwt') {
  private logger = new Logger('JwtAuthGuard');

  constructor(private readonly jwtService: JwtService) {
    super();
  }

  async canActivate(context: ExecutionContext): Promise<any> {
    const request = context.switchToHttp().getRequest();
    const { path, method } = request;

    // 检查当前请求是否在排除列表中
    const isExcluded = excludedRoutes.some(
      (route) => route.path === path && route.method === method,
    );

    if (isExcluded) {
      return true; // 如果请求被排除，则不进行 JWT 验证
    }

    const token = request.get('Authorization');

    this.logger.log('@@@@ token：', token);

    if (!token) {
      throw new UnauthorizedException('没有token，请先登录');
    }

    // Bearer token 格式
    const bearerToken = token.split(' ');

    if (bearerToken.length < 2 || bearerToken[0] !== 'Bearer') {
      throw new UnauthorizedException('token格式或类型不正确');
    }

    try {
      const decoded = await this.jwtService.verifyAsync(bearerToken[1]);
      // 令牌验证成功
      if (decoded) {
        request.user = decoded;
        return this.activate(context);
      }
    } catch (error) {
      throw new UnauthorizedException('没有权限，请登录');
    }
  }

  async activate(context: ExecutionContext): Promise<boolean> {
    return super.canActivate(context) as Promise<boolean>;
  }
}
